﻿using Newtonsoft.Json;
using System.Text;
using System.Web;

namespace dy.net.utils
{
    public class BogusManager
    {
        /// <summary>
        /// 字符串方法生成X-Bogus参数
        /// </summary>
        /// <param name="endpoint">请求端点</param>
        /// <param name="userAgent">用户代理</param>
        /// <returns>带X-Bogus的完整端点</returns>
        public static string XbStr2Endpoint(string endpoint, string userAgent)
        {
            try
            {
                var (finalEndpoint, _) = XBogusManager.GetXBogus(endpoint, userAgent);
                return finalEndpoint;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"生成X-Bogus失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 字典方法生成X-Bogus参数
        /// </summary>
        /// <param name="baseEndpoint">基础端点</param>
        /// <param name="parameters">请求参数</param>
        /// <param name="userAgent">用户代理</param>
        /// <returns>带X-Bogus的完整端点</returns>
        public static string XbModel2Endpoint(string baseEndpoint, Dictionary<string, string> parameters, string userAgent)
        {
            if (parameters == null)
                throw new ArgumentException("参数必须是字典类型");

            // 构建参数字符串
            var paramStr = string.Join("&", parameters.Select(kv => $"{kv.Key}={HttpUtility.UrlEncode(kv.Value)}"));

            try
            {
                var (_, xbValue) = XBogusManager.GetXBogus(paramStr, userAgent);
                // 检查基础端点是否已有查询参数
                var separator = baseEndpoint.Contains("?") ? "&" : "?";
                return $"{baseEndpoint}{separator}{paramStr}&X-Bogus={xbValue}";
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"生成X-Bogus失败: {ex.Message}");
            }
        }
    }

    public static class XBogusManager
    {
        /// <summary>
        /// 生成X-Bogus签名
        /// </summary>
        /// <param name="input">输入字符串（参数或完整URL）</param>
        /// <param name="userAgent">用户代理</param>
        /// <returns>（带签名的URL，签名值）</returns>
        public static (string, string) GetXBogus(string input, string userAgent)
        {
            // X-Bogus核心算法实现（参考公开逆向分析结果）
            // 注意：该算法可能随版本更新而变化，需根据实际情况调整

            // 1. 提取关键信息
            var isUrl = input.Contains("http") || input.Contains("?");
            string queryString = isUrl ? HttpUtility.ParseQueryString(new Uri(input).Query).ToString() : input;

            // 2. 生成基础哈希
            var hash = GenerateBaseHash(queryString, userAgent);

            // 3. 应用签名算法
            var xbValue = ComputeXBogus(hash, userAgent);

            // 4. 构建结果
            if (isUrl)
            {
                var uri = new Uri(input);
                var newQuery = string.IsNullOrWhiteSpace(uri.Query)
                    ? $"X-Bogus={xbValue}"
                    : $"{uri.Query.Substring(1)}&X-Bogus={xbValue}";
                return ($"{uri.Scheme}://{uri.Host}{uri.AbsolutePath}?{newQuery}", xbValue);
            }
            else
            {
                return ($"X-Bogus={xbValue}", xbValue);
            }
        }

        private static string GenerateBaseHash(string input, string userAgent)
        {
            // 基础哈希计算逻辑
            using (var sha1 = System.Security.Cryptography.SHA1.Create())
            {
                var bytes = Encoding.UTF8.GetBytes($"{input}_{userAgent}_3.0.0");
                var hashBytes = sha1.ComputeHash(bytes);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            }
        }

        private static string ComputeXBogus(string baseHash, string userAgent)
        {
            // 核心签名计算（模拟算法，实际需根据最新逆向结果调整）
            var time = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
            var rand = new Random();
            var randStr = new string(Enumerable.Repeat("abcdefghijklmnopqrstuvwxyz0123456789", 6)
                .Select(s => s[rand.Next(s.Length)]).ToArray());

            // 组合签名
            return $"DFSz{time:x8}{randStr}{baseHash.Substring(0, 16)}";
        }
    }

    // 其他辅助类示例
    public class TokenManager
    {


        /// <summary>
        /// 生成msToken
        /// </summary>
        public static async Task<string> GenRealMsTokenAsync()
        {

            try
            {
                using HttpClient _httpClient = new HttpClient();
                var payload = new
                {
                    magic = 538969122,
                    version = 1,
                    dataType = 8,
                    strData = @"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",
                    tspFromClient = DateTimeUtil.GetUnixTimestampMilliseconds()
                };

                var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");
                _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.47");

                var response = await _httpClient.PostAsync("https://mssdk.bytedance.com/web/report", content);
                response.EnsureSuccessStatusCode();
                var sss = await response.Content.ReadAsStringAsync();
                //var cookies = response.Headers.GetValues("Set-Cookie");

                var msToken = response.Headers.GetValues("X-Ms-Token").FirstOrDefault();

                //var msToken = cookies.FirstOrDefault(c => c.StartsWith("msToken="))?.Split(';')[0].Split('=')[1];

                if (msToken != null && (msToken.Length != 120 || msToken.Length != 128))
                    return msToken;

                throw new Exception("msToken格式不正确");
            }
            catch (Exception ex)
            {
                // 生成虚假token
                return GenFalseMsToken();
            }
        }

        public static string GenFalseMsToken()
        {
            var rand = new Random();
            var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            return new string(Enumerable.Repeat(chars, 126)
                .Select(s => s[rand.Next(s.Length)]).ToArray()) + "==";
        }
    }
}
